import { CommonUtils } from "./CommonUtils";
import { EventManager } from "./EventManager";
import { EventType } from "./EventType";
import { ISingleton } from "./ISingleton";

interface goodData {
    "key": "small",	//货物规格标识
    "width": 0.2,		//货物宽度
    "high": 0.2,		//货物高度
    "is_fragile": false,	//是否易碎,True为易碎
    "sku_num": 5,	//该规格货物sku数量
    "frequency": 0.5	//该规格货物总进出库占比
}

interface BaseData  {
    "shelf_num": 5,  //货架数
    "shelf_cell_num": 3, //货架层数
    "shelf_high_per_cell": 3,  //货架层高
    "shelf_width": 20,  //货架长度
    "goods":  [goodData] //货物规格清单
}

export default class Execute  extends ISingleton {

    // 基础数据
    _baseData:BaseData;
    // 当天的数据
    _dayData:Array<Array<any>>;
    // 当天数据的一份深拷贝，排序
    _dayResortData:Array<Array<any>>;

    // 位置数据信息  1空地，2被正常物品占据，3被易碎物品占据
    _posArr:Array<Array<any>>;

    _sendData = [];

    public async initData(){
        const data = await CommonUtils.GetInstance().loadJson('txt/base');
        this._baseData = data as BaseData;
        this.initShelf();

        await this.loadDayData(1);
        // 根据宽度降序排列
        this.downList(this._dayResortData);

        // 找到每个商品的定位
        for(let i=0;i<this._dayResortData.length;i++){
            this.findPerGoodPos(this._dayResortData[i]);
        }
        cc.log(this._sendData)
this.creatorBox()
        // 按照初始顺序处理
        for(let i=0;i<this._dayData.length;i++){
            this.in(this._dayData[i]);
        }
        // console.log(this._dayData);
        // console.log(this._dayResortData);

        // console.log(this._posArr);
    }

    // 二维化书架位置
    public initShelf(){
        // this.initPerFloor();
        const arr = []
        for(let i =0;i<this._baseData.shelf_num;i++){
            for (let j=0;j<this._baseData.shelf_cell_num;j++){
                if(j==0){
                    arr[i] = [];
                }
                arr[i][j] = this.initPerFloor();
            }
        }
        // console.log(arr);
        this._posArr = arr;
    }   

    public initPerFloor(){
        // 单层的高度
        const perFloorLine = this._baseData.shelf_high_per_cell*10;
        // 单层的行数
        const perFloorRow = this._baseData.shelf_width*10;
        const arr = [];
        for(let i=0;i<perFloorLine;i++){
            for(let j=0;j<perFloorRow;j++){
                if(j==0){
                    arr[i] = [];
                }
                arr[i][j]=1;
            }
        }
        // console.log(arr);   
        return arr;
    }

    public downList(list:Array<Array<any>>){
        list.sort((a, b) => b[4].width - a[4].width);
    }


    public splitStringByNewline(str) {
        return str.split('\n');
    }

    public splitStringByHandle(str) {
        return str.split(',');
    }

    // 某天入库出库的数据
    public async loadDayData(day:number){
        const data = await CommonUtils.GetInstance().loadTxt('txt/' + day);
        this._dayData = this.splitStringByNewline(data);
        this._dayResortData = [];
        for(let i=0;i<this._dayData.length;i++){
            // str类型，直接复制就是深拷贝了
            this._dayResortData[i] = this._dayData[i];
            this._dayResortData[i] = this.splitStringByHandle(this._dayResortData[i]);
            this._dayData[i] = this.splitStringByHandle(this._dayData[i]);
            
            if(this._dayData[i][1])
                for(let j=0;j<this._baseData.goods.length;j++){
                    if(this._dayData[i][1] == this._baseData.goods[j].key){
                        this._dayData[i].push(this._baseData.goods[j]);
                        this._dayResortData[i].push(this._baseData.goods[j]);
                    }
                }
        }

        // 数据处理会导致最后一行是空的
        this._dayData.pop();
        this._dayResortData.pop();
    }

    // 商品入库
    public in(data){

    }

    // 商品出库
    public out(data){

    }

    public async findPerGoodPos(boxData){
        // 寻找书架
        for(let i=0;i<this._posArr.length;i++){
            // 寻找层
            for(let j=0;j<this._posArr[i].length;j++){
                // 单层遍历寻找空间
                const floorData = this._posArr[i][j];
                for(let x = floorData.length-1;x>=0;x--){
                    for(let y = 0;y<floorData[x].length;y++){
                        // 最大的放底部  
                        // 找到第一个空地
                        if(floorData[x][y] == 1){
                            const boxWidth = boxData[4].width*10;
                            const high = boxData[4].high*10;
                            if(x - high > 0 
                                &&  floorData[x][y+boxWidth]
                                &&  floorData[x][y + boxWidth] == 1
                                ){
                                    const tag = boxData[4].is_fragile?2:3;
                                    // console.log("找到空地,占据为",tag);
                                    for(let a = x;a>x-high;a--){
                                        for(let b = y;b<y+boxWidth;b++){
                                            this._posArr[i][j][a][b] = tag;
                                        }
                                    }
                                    const sendData = {
                                        shelfNum :i,
                                        floorNum :j,
                                        posX:x,
                                        posY:y,
                                        box:boxData
                                    };
                                    this._sendData.push(sendData)
                                    // await CommonUtils.GetInstance().sleepTime(100);
                                    // EventManager.Instance.dispatch(EventType.FLY_BOX,sendData);
                                    break;
                            }
                        }
                    }
                }
            }
        }
        // console.log('没找到空地');
    }

    async creatorBox(){
        // cc.log(this._sendData)
        for (let i = 0; i < this._sendData.length; i++) {
            await CommonUtils.GetInstance().sleepTime(1 * i);
            // const element = array[i];
            EventManager.Instance.dispatch(EventType.FLY_BOX,this._sendData[i]);
        }
    }
}
